package dev.ece.suit.loader.models.fbx;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang3.StringUtils;

public class FBXSkin {

	public static final String SKIN = "Skin";
	
	private long id;
	
	public static FBXSkin[] parseFBXSkin(List<FBXElement> elements) {
		if(elements != null && !elements.isEmpty()) {
			List<FBXSkin> result = new ArrayList<FBXSkin>();
			FBXSkin skin = null;
			for(FBXElement element: elements) {
				if(StringUtils.equals(SKIN, (String) element.getProperties()[2].getValue())) {
					skin = new FBXSkin();
					skin.id = (Long) element.getProperties()[0].getValue();
					result.add(skin);
				}
			}
			return result.toArray(new FBXSkin[] {});
		}
		return null;
	}
	
	public static Map<Long, FBXSkin> toFBXSkinMap(FBXSkin[] skins) {
		Map<Long, FBXSkin> result = new ConcurrentHashMap<Long, FBXSkin>();
		if(skins != null && skins.length > 0) {
			for(FBXSkin skin: skins) {
				result.put(skin.getId(), skin);
			}
		}
		return result;
	}
	
	public static void connectJointToGeometry(Map<Long, List<FBXConnection>> connections, FBXSkin[] skins, FBXJoint[] joints, FBXGeometry[] geometries, FBXModel[] models) {
		if(joints != null && joints.length > 0) {
			Map<Long, FBXGeometry> map = FBXGeometry.toFBXGeometryMap(connections, geometries);
			Map<Long, FBXModel> modelmap = FBXModel.toFBXModelMap(models);
			Map<Long, FBXSkin> skinmap = FBXSkin.toFBXSkinMap(skins);
			List<FBXConnection> conns = null;
			List<FBXConnection> cconns = null;
			List<FBXConnection> ccconns = null;
			FBXGeometry geometry = null;
			FBXModel meshModel = null;
			FBXSkin skin = null;
			for(int i=0; i<joints.length; i++) {
				conns = connections.get(joints[i].getId());
				if(conns != null) {
					for(FBXConnection conn: conns) {
						skin = skinmap.get(conn.getTo());
						if(skin != null) {
							cconns = connections.get(skin.getId());
							if(cconns != null) {
								for(FBXConnection cconn: cconns) {
									geometry = map.get(cconn.getTo());
									if(geometry != null) {
										geometry.fillBoneWeights(i, joints[i]);
									}
								}
							}
						}
					}
				}
			}
			if(geometries != null && geometries.length > 0) {
				for(FBXGeometry geo: geometries) {
					ccconns = connections.get(geometry.getId());
					if(ccconns != null) {
						for(FBXConnection ccconn: ccconns) {
							meshModel = modelmap.get(ccconn.getTo());
							if(meshModel != null) {
								geo.setMeshModel((FBXMeshModel) meshModel);
							}
						}
					}
				}
			}
		}
	}

	public long getId() {
		return id;
	}
	
}
